<?php

namespace IYUU\sdk\CoolQ;

require_once __DIR__ . '/Version.php';
require_once __DIR__ . '/helpers.php';

use BadRequestException;
use Exception;
use InternalServerErrorException;
use Middleware;
use Response;
use Throwable;
use Yaf\Registry;

/**
 * 机器人的消息路由器
 * Class BotResponse
 * @package IYUU\sdk\CoolQ
 */
class BotResponse extends Response
{
    /**
     * 请求对象
     * @var Request
     */
    private $request;

    /**
     * 初始化函数
     *
     * @param string|int $qq
     * @return BotResponse
     * @throws BadRequestException
     */
    public function init($qq): BotResponse
    {
        // 1.检查当前机器人的配置是否存在（支持多机器人）
        $config = include static::getConfigPath();
        if (empty($config[$qq])) {
            throw new BadRequestException('机器人QQ未配置：' . $qq);
        }
        $self = $config[$qq];

        // 2.请求对象
        $this->request = new Request();

        // 3.OneBotApi对象
        $OneBotApi = new OneBotApi($self['host'], $self['token']);
        /**
         * 把对象放入注册表
         */
        Registry::set(Registry_CONFIG_NAME, $self);             // 当前机器人的配置
        Registry::set(Registry_ONEBOT_NAME, $OneBotApi);        // OneBotApi对象

        // 4.初始化中间件
        Middleware::load($self['middleware']);
        return $this;
    }

    /**
     * 响应操作
     *
     * @return $this
     */
    public function response(): BotResponse
    {
        // 开始调度
        try {
            // 创建事件处理类
            $class = Factory::generateService($this->request);
            $action = $this->request->getServiceAction();
            // 把上下文对象作为参数，传入中间件和事件处理类
            $callback = Middleware::getCallback('bot', array($class, $action));
            $this->data = $callback(Registry::get(Registry_CONTEXT_NAME));
        } catch (BadRequestException|InternalServerErrorException $ex) {
            // 框架可控的异常
            $this->setException($ex);
        } catch (Throwable $ex) {
            // 不可控的异常
            http_response_code(500);
            file_put_contents(runtime_path() . '/Exception.log', __METHOD__ . p($this->request->getAll(), false), FILE_APPEND);
            file_put_contents(runtime_path() . '/Exception.log', __METHOD__ . p($ex, false), FILE_APPEND);
            $this->setException($ex);
        }
        // 结束调度
        return $this;
    }

    /**
     * 设置异常代码、异常消息
     *
     * @param Exception $ex
     * @return BotResponse
     */
    protected function setException(Throwable $ex): BotResponse
    {
        $this->ret = $ex->getCode();
        $this->msg = $ex->getMessage();
        $this->data = [
            'reply' => $ex->getMessage(),
            'auto_escape' => false
        ];
        return $this;
    }

    /**
     * 获取返回结果
     */
    protected function getResult(): array
    {
        // OneBot数据结构
        file_debug($this->data, __FUNCTION__);

        return $this->data;
    }

    /**
     * 获取配置文件完整路径
     * @return string
     */
    public static function getConfigPath(): string
    {
        return APPLICATION_PATH . '/conf/' . ini_get('yaf.environ') . '/bot.php';
    }
}
